package ac.il.technion.cs236369.hw5.core.xslt;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.log4j.Logger;

import ac.il.technion.cs236369.hw5.core.entities.User;
import ac.il.technion.cs236369.hw5.core.entities.XsltStorage;

public enum XsltStorageParameters {

	XSLT_ID( "id") {
		public void saveParameter( XsltStorage storage, Map<String, String> parameters, EntityManager manager) {
			// Do nothing
		}
	},
	XSLT_TYPE( "type") {
		public void saveParameter( XsltStorage storage, Map<String, String> parameters, EntityManager manager) {
			String type = parameters.get( toString( ));
			if ( type != null)
				storage.setType( type);
		}
	},
	XSLT_NAME( "name") {
		public void saveParameter( XsltStorage storage, Map<String, String> parameters, EntityManager manager) {
			String name = parameters.get( toString( ));
			if ( name != null)
				storage.setName( name);
		}
	},
	XSLT_POSTED_BY( "postedBy") {
		public void saveParameter( XsltStorage storage, Map<String, String> parameters, EntityManager manager) {
			String postedBy = parameters.get( toString( ));
			if ( postedBy != null && postedBy.length( ) > 0) {
				User user = manager.find( User.class, postedBy);
				storage.setPostedBy( user);
			}
		}
	},
	XSLT_CONTENT( "content") {
		@SuppressWarnings( "unchecked")
		public void saveParameter( XsltStorage storage, Map<String, String> parameters, EntityManager manager) {
			String content = parameters.get( toString( ));
			if ( content != null)
				storage.setContent( content);
		}
	},
	UNDEFINED( "undefined") {
		public void saveParameter( XsltStorage storage, Map<String, String> parameters, EntityManager manager) {
			// do nothing operation is not defined.
		}
	};
	
	
	private String name;

	protected static Logger logger = Logger.getLogger( XsltStorageParameters.class);

	public static Map<String, String> getParameters( HttpServletRequest request) {
		Map<String, String> res = new HashMap<String, String>( );
		if ( !ServletFileUpload.isMultipartContent( request))
			return request.getParameterMap( );
		ServletFileUpload upload = new ServletFileUpload( new DiskFileItemFactory( ));
		try {
			@SuppressWarnings( "cast")
			List<FileItem> items = (List<FileItem>)upload.parseRequest( request);
			for ( FileItem item : items) {
				if ( !item.isFormField( )) {
					InputStream is = item.getInputStream( );
					BufferedReader reader = new BufferedReader( new InputStreamReader( is));
					StringBuilder builder = new StringBuilder( );
					String $ = null;
					while ( ( $ = reader.readLine( )) != null) {
						builder.append( $);
					}
					res.put( "content", builder.toString( ));
				} else {
					InputStream inputStream = item.getInputStream( );
					BufferedReader reader = new BufferedReader( new InputStreamReader( inputStream));
					res.put( item.getFieldName( ), reader.readLine( ));
				}
			}
		} catch ( FileUploadException e) {
			logger.error( e);
		} catch ( IOException e) {
			logger.error( e.getMessage( ));
		}
		return res;
	}
	
	private static Map<String, XsltStorageParameters> map = new HashMap<String, XsltStorageParameters>( );
	
	static {
		for ( XsltStorageParameters $ : XsltStorageParameters.values( )) {
			map.put( $.name, $);
		}
	}
	
	private XsltStorageParameters( String name) {
		this.name = name;
	}
	
	@Override 
	public String toString( ) {
		return name;
	}
	
	public XsltStorageParameters fromString( String name) {
		XsltStorageParameters $ = map.get( name);
		if ( null != $)
			return $;
		return UNDEFINED;
	}
	
	abstract public void saveParameter( XsltStorage storage, Map<String, String> parameters, EntityManager manager);
}
